/**
 * Copyright 2018 orivil.com. All rights reserved.
 * Use of this source code is governed by a MIT-style
 * license that can be found at https://mit-license.org.
 */

package export

import (
	"runtime"
	"path/filepath"
	"os"
	"strings"
	"io"
	"log"
)

// 导出静态文件，将 ExportFiles() 函数目录下的 srcDir 文件夹下的所有文件都复制到 dstDir 目录下
// 如果有文件已经存在则跳过, srcDir 下的所有以 "." 开头的目录都将被忽略
func ExportFiles(dstDir string, srcDir string, logger *log.Logger) error {
	_, file, _, _ := runtime.Caller(1)
	codeDir := filepath.Dir(file)
	exportDir := filepath.Join(codeDir, srcDir)
	err := filepath.Walk(exportDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		subPath := strings.TrimPrefix(path, exportDir)
		linkPath := filepath.Join(dstDir, subPath)
		if info.IsDir() {
			// 跳过 . 开头的目录
			if strings.HasPrefix(info.Name(), ".") {
				return filepath.SkipDir
			}
			// 创建目录
			err = os.MkdirAll(linkPath, 0777)
			if err != nil {
				return err
			}
		} else {
			// copy 文件
			dst, err := os.OpenFile(linkPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0777)
			defer func() {
				if dst != nil {
					dst.Close()
				}
			}()
			if err != nil {
				if os.IsExist(err) {
					if logger != nil {
						logger.Printf("目标文件 %s 已存在, 跳过迁移\n", linkPath)
					}
					return nil
				} else {
					return err
				}
			}
			src, err := os.OpenFile(path, os.O_RDONLY, 0777)
			if err != nil {
				return err
			}
			defer func() {
				if src != nil {
					src.Close()
				}
			}()
			_, err = io.Copy(dst, src)
			if err != nil {
				return err
			}
			if logger != nil {
				logger.Printf("文件已迁移 %s ->\n %s\n", path, linkPath)
			}
		}
		return nil
	})
	if err != nil {
		return err
	}
	return nil
}
